package com.baitiaojun.video.service.impl;

import com.baitiaojun.api.domain.video.File;
import com.baitiaojun.api.exception.ConditionException;
import com.baitiaojun.api.util.*;
import com.baitiaojun.api.vo.FileInfo;
import com.baitiaojun.video.handler.FrameGrabHandler;
import com.baitiaojun.video.mapper.FileMapper;
import com.baitiaojun.video.service.FileService;
import com.baitiaojun.video.support.FastDFSSupport;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Map;

/**
 * @类名 FileServiceImpl
 * @描述 TODO
 * @作者 白条君
 * @创建日期 2022/12/18 13:59
 * @版本 1.0
 */
@Service
public class FileServiceImpl implements FileService {

    @Resource
    private FileMapper fileMapper;

    @Resource
    private FastDFSSupport fastDFSSupport;

    @Autowired
    private FrameGrabHandler frameGrabHandler;

    @Override
    public String getFileMd5(MultipartFile file) {
        return MD5Util.getFileMd5(file);
    }

    @Override
    public FileInfo fastUploadFile(MultipartFile multipartFile, String group, String md5, Integer sliceNo, Integer totalSize) throws Exception {
        if (ObjectUtils.isEmpty(group)) {
            throw new ConditionException("参数异常");
        }
        String url = fileMapper.getUrlByMd5(md5);
        if (ObjectUtils.isNotEmpty(url)) {
            AESUtil aesUtil = AESUtil.lazyGetAesUtil();
            String encryptPath = aesUtil.encrypt(url);
            //获取文件时长进行返回
            Map<String, String> splitFile = FileUtil.splitFilePath(url);
            String localPath = fastDFSSupport.downLoadFile(splitFile.get("group"), splitFile.get("filePath"));
            String duration = FileUtil.getDuration(localPath);
            FileUtil.deleteFile(FileUtil.getFileName(url));
            //获取视频封面
            File fileByMd5 = fileMapper.getFileByMd5(md5);
            if (ObjectUtils.isEmpty(fileByMd5)) {
                throw new ConditionException("该视频文件不存在");
            }
            Long id = fileByMd5.getId();
            String thumbnailPath = frameGrabHandler.genericVideoFrame(id, md5);
            FileUtil.deleteFile(id + "." + fileByMd5.getType());
            if (StringUtils.isEmpty(thumbnailPath) && StringUtils.isBlank(thumbnailPath)) {
                throw new ConditionException("无法获取视频封面");
            }
            return FileInfo.builder().path(encryptPath).duration(duration).thumbnailPath(thumbnailPath).process("100%").build();
        }
        FileInfo fileInfo = fastDFSSupport.uploadAppendFile(multipartFile, group, md5, sliceNo, totalSize);
        String path = fileInfo.getPath();
        if (StringUtils.isNotBlank(path)) {
            //将文件信息保存到数据库
            Long id = SnowFlakeUtil.getNextId();
            int res = fileMapper.insertSelective(File.builder().id(id)
                    .url(path)
                    .md5(md5)
                    .type(FileUtil.getType(multipartFile))
                    .createtime(new Date())
                    .build());
            if (res == 0) {
                throw new ConditionException("文件添加失败");
            }
            //获取视频封面
            String thumbnailPath = frameGrabHandler.genericVideoFrame(id, md5);
            if (StringUtils.isNotEmpty(thumbnailPath) && StringUtils.isNotBlank(thumbnailPath)) {
                fileInfo.setThumbnailPath(thumbnailPath);
            }
            //获取文件时长进行返回
            Map<String, String> splitFilePath = FileUtil.splitFilePath(path);
            String storageGroup = "group1";
            String storagePath = splitFilePath.get("filePath");
            String localPath = fastDFSSupport.downLoadFile(storageGroup, storagePath);
            String duration = FileUtil.getDuration(localPath);
            fileInfo.setDuration(duration);
            FileUtil.deleteFile(FileUtil.getFileName(path));
        }
        //对path加密处理后返回
        if (StringUtils.isNotBlank(path)) {
            AESUtil aesUtil = new AESUtil(ConstantUtil.AES_SEED);
            String encryptPath = aesUtil.encrypt(path);
            fileInfo.setPath(encryptPath);
        }
        return fileInfo;
    }
}
